/*
 * @Author: wuqingchun
 * @Date: 2024-07-23 14:06:06
 * @Description: 固定大小对象内存池
 * @LastEditors: wuqingchun
 * @LastEditTime: 2024-07-23 16:28:06
 */
#ifndef __OBJECT_POOL_H__
#define __OBJECT_POOL_H__

#include <iostream>

template <typename T>
class ObjectPool
{
private:
    static constexpr size_t EXPANSION_COUNT = 1024;
public:
    T* New()
    {
        if (m_pFreeList == nullptr)
        {
            __ExpandPool(EXPANSION_COUNT);
            if (m_pFreeList == nullptr)
            {
                return nullptr;
            }
        }

        void* pObj = m_pFreeList;
        m_pFreeList = *(void **)m_pFreeList;

        // 调用 T 的构造函数
        //在已分配的内存上使用定位 new 构造对象
        new (pObj) T;
        
        return (T*)pObj;
    }

    void Delete(T* pobjT)
    {
        if (pobjT == nullptr)
        {
            return;
        }

        //显示调用该对象的析构函数清理该对象 防止该来中有动态资源没有释放造成内存泄漏。
        pobjT->~T();

        *(void**)pobjT = m_pFreeList;
        m_pFreeList = pobjT;
    }

private:
    void __ExpandPool(size_t ulCount)
    {
        size_t ulOneSize = sizeof(void*) > sizeof(T) ? sizeof(void*) : sizeof(T);
        
        // TODO pcMem 内存存在泄露
        char* pcMem = new char[ulOneSize * ulCount]; 
        if (pcMem == nullptr)
        {
            return;
        }

        m_pFreeList = pcMem;
        for (size_t ulIndex = 0; ulIndex < EXPANSION_COUNT - 1; ulIndex++)
        {
            *(void**)pcMem = pcMem + ulOneSize;
            pcMem += ulOneSize;
        }

        *(void**)pcMem = nullptr;
    }
private:
    void* m_pFreeList = nullptr;
};

#endif //__OBJECT_POOL_H__